#pragma once
#include "Sock.hpp"
#include <cstdint>
#include<iostream>
#include<functional>
#include <netinet/in.h>
#include <pthread.h>
#include <string>
#include<vector>
#include<unistd.h>

namespace yangyi
{
    typedef std::function<void(int)>func_t;
    class TcpServer;
    class ThreadData
    {
    public:
        ThreadData(int sock,TcpServer* server)
        :_sock(sock)
        ,_server(server)
        {

        } 
        ~ThreadData(){

        }
    public:
        int _sock;
        TcpServer* _server;
    };
    class TcpServer
    {
    public:
        TcpServer(const uint16_t port,std::string ip)
        {
            _serversock=_sock.Socket();
            _sock.Bind(_serversock);
            _sock.Listen(_serversock);
        }
        void BindHandler(func_t callback)
        {
            for(auto& iter:_funcs){
                _funcs.push_back(callback);
            }
        }
        void Excute(int sock){
            for(auto& iter:_funcs){
                iter(sock);
            }
        }
        void Start(){
            while(true)
            {
                std::string clientip;
                uint16_t clientport;
                int sock=_sock.Accept(_serversock,&clientport,clientip);
                if(sock == -1){
                    continue;
                }
                pthread_t tid;
                ThreadData* args=new ThreadData(sock,this);
                pthread_create(&tid, nullptr, ThreadRoutine, (void*)args);
            }
        }
        ~TcpServer(){
            if(_serversock >= 0){
                close(_serversock);
            }
        }
    private:
        int _serversock;
        Sock _sock;
        std::vector<func_t>_funcs;
    };
}
// namespace ns_tcpserver
// {
//     class TcpServer;
//     typedef std::function<void(int)>func_t;
//     class ThreadData
//     {
//     public:
//         ThreadData(int sock,TcpServer* server)
//         :_sock(sock)
//         ,_server(server)
//         {

//         }
//         ~ThreadData(){

//         }
//     public:
//         int _sock;
//         TcpServer* _server;
//     };

//     class TcpServer
//     {
//     public:
//         TcpServer(const uint16_t& port,const std::string& ip="0.0.0.0")
//         {
//            _serversock=_sock.Socket();
//            _sock.Bind(_serversock,port,ip);
//            _sock.Listen(_serversock);
//         }
//         void BindHandler(func_t callback)
//         {
//             _funcs.push_back(callback);
//         }
//         void Excute(int sock)
//         {
//             for(auto& iter:_funcs){
//                 iter(sock);
//             }
//         }
//         void start()
//         {
//             while(true)
//             {
//                 std::string clientip;
//                 uint16_t clientport;
//                 //让他接受来自于服务端的套接字
//                 int sock=_sock.Accept(_serversock,&clientport,&clientip);
//                 if(sock==-1){
//                     continue;
//                 }
//                 pthread_t tid;
//                 ThreadData* td=new ThreadData(sock,this);
//                 pthread_create(&tid, nullptr, ThreadRoutine, td);
//             }
//         }
//         void Start(){
//             while(true){
//                 std::string clientip;
//                 uint16_t clientport;
//                 //这里都是从客户端那里接受到的消息
//                 int sock=_sock.Accept(_serversock,&clientport,&clientip);
//                 if(sock ==-1){
//                     continue;
//                 }
//                 pthread_t tid;
//                 ThreadData* td=new ThreadData(sock,this);
//                 pthread_create(&tid, nullptr, ThreadRoutine, ()td);
//             }
//         }
//         ~TcpServer(){
//             if(_serversock>=0){
//                 close(_serversock);
//             }
//         }
//     private:
//         static void* ThreadRoutine(void* args)
//         {
//             //这里就去执行任务
//             pthread_detach(pthread_self());
//             ThreadData* td=static_cast<ThreadData*>(args);
//             td->_server->Excute(td->_sock);
//             close(td->_sock);
//             return nullptr;
//         }
//     private:
//         int _serversock;
//         Sock _sock;
//         std::vector<func_t> _funcs;
//     };
// }
// class Sock
// {
// public:
//     Sock(){}
//     int Socket()
//     {
//         int serversock=socket(AF_INET, SOCK_DGRAM, 0);
//         if(serversock < 0)
//         {
//             LogMessage(FATAL, "%d:%s",errno ,strerror(errno));
//             exit(2);
//         }
//         LogMessage(NORMAL, "create socket done :%d",serversock);
//         return serversock;
//     }
//     void Bind(int sock,uint16_t port,std::string ip="0.0.0.0")
//     {
//         struct sockaddr_in server;
//         socklen_t len=sizeof(server);
//         bzero(&server,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(port);
//         server.sin_addr.s_addr=inet_addr(ip.c_str());
//         if(bind(sock, (struct sockaddr*)&server, len) < 0)
//         {
//             LogMessage(FATAL, "%d:%s",errno, strerror(errno));
//             exit(2);
//         }
//     }
//     void Listen(int sock)
//     {
//         if(listen(sock, gbackLog) < 0)
//         {
//             LogMessage(FATAL, "%d:%s",errno,strerror(errno));
//             exit(2);
//         }
//         LogMessage(NORMAL,"listen done");
//     }
//     //既然这里是输出型参数，只需要等待别人的数据即可
//     int Accept(int sock,uint16_t* port,std::string* ip)
//     {
//         struct sockaddr_in client;
//         socklen_t len=sizeof(client);
//         //这一步本身就是初始化的一个过程
//         int serversock=accept(sock, (struct sockaddr*)&client, &len);
//         if(serversock < 0)
//         {
//             LogMessage(FATAL, "%d:%s",errno, strerror(errno));
//             return -1;
//         }
//         if(port){
//             *port=ntohs(client.sin_port);
//         }
//         if(ip){
//             *ip=inet_ntoa(client.sin_addr);
//         }
//     }
//     bool Cannet(int sock,uint16_t& port,std::string& ip)
//     {
//         struct sockaddr_in server;
//         socklen_t len=sizeof(server);
//         memset(&server,0,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(port);
//         server.sin_addr.s_addr=inet_addr(ip.c_str());
//         if(connect(sock, (struct sockaddr*)&server, len) == 0){
//             return true;
//         }
//         else{
//             return false;
//         }
//     }
//     ~Sock(){

//     }
// private:
//     const int gbackLog=20;
// };
